package gate

import (
	"errors"
	"net"
	"github.com/liu-junyong/go-logger/logger"
	"fmt"
	"bufio"
	"bytes"
	"encoding/binary"
	"encoding/json"
	"time"
	. "../configs"
)


type  TcpSession struct{
	//Uri	string
	Gt	GateNodeConfig
	Con	*net.Conn
	CM *TcpManager
	Status int //0:不可用  1:正在连接 2:已经连接 3:其他
}



type TcpHead struct {
	Cmd            int16
	ClientIDLength int16
}


func (this *TcpSession)Loop(){
	con := *this.Con
	buf := bufio.NewReadWriter(bufio.NewReader(con), bufio.NewWriter(con))
	defer con.Close()
	for {
		bts, err := buf.ReadSlice('\n')

		if err != nil {
			logger.Error("get client data error: ", err)
			return
		}

		if len(bts) < 4 {
			logger.Error(bts)
			return
		}

		hd := TcpHead{}
		binary.Read(bytes.NewBuffer(bts), binary.BigEndian, &hd)
		if 4+int(hd.ClientIDLength) > len(bts) {
			logger.Error(4 + int(hd.ClientIDLength))
			return
		}
		data := bts[4+hd.ClientIDLength:]
		ClientID := ""
		if hd.ClientIDLength > 0 {
			ClientID = string(bts[4 : 4+hd.ClientIDLength])
			//fmt.Sprintln(ClientID)
		}
		//go DoUser(ConnectionID, GameServerID, &hd, string(data), ClientID)
		logger.Info(ClientID,string(data))

	}
	this.Status = 3

}



func DoUser(tcpConnection string, GameServerID string, hd *TcpHead, str string, clientID string) {

	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	logger.Info(str)
	var adp FullPackage
	json.Unmarshal([]byte(str), &adp)
	if adp.Uid == 0 {
		logger.Error("没有用户数据:", str, "解析结果：", adp.Uid, clientID, adp.Data, adp.Dt, adp.Code)
		return
	}

}


func (this *TcpSession)MergeStatus(gt *GateNodeConfig) {
	this.Gt = *gt
}


type RegisterServer struct {
	Op string	`json:op`
	Id string	`json:id`
}
func (this *TcpSession)Init(gt *GateNodeConfig){
	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	this.Gt = *gt
	endpoint := gt.Endpoint//fmt.Sprintf("%s:%d",this.Gt.Ip,this.Gt.Port)
	this.Status = 1


	c,e := net.DialTimeout("tcp",endpoint,time.Second*15)
	if e != nil {
		logger.Error(" 无法连接：",this.Gt)
		time.Sleep( time.Second )
		return
	}else{
		logger.Info( this.Gt,"连接到：")
	}
	this.Status = 2
	this.Con = &c

	adp := RegisterServer{"register_back_server",this.Gt.Endpoint}
	bt,_ := json.Marshal(&adp)
	c.Write(bt)
}




func (this *TcpSession) Send2BackJson(clientid string,str string)error {

	defer func() {
		if r := recover(); r != nil {
			logger.Error(r)
		}
	}()

	c := int16('U')
	clientLen := int16(len(clientid))

	buf := bytes.NewBuffer([]byte{})
	binary.Write(buf, binary.BigEndian, &c)
	binary.Write(buf, binary.BigEndian, &clientLen)
	binary.Write(buf, binary.BigEndian, []byte(clientid))
	binary.Write(buf, binary.BigEndian, []byte(str))


	conn := this.Con
	if conn == nil {
		logger.Info("找不到连接", clientid,this.Gt)
		return errors.New(fmt.Sprintf("找不到连接 client:%s 服务器信息:%v", clientid,this.Gt))
	}
	tcpConnect := bufio.NewReadWriter(bufio.NewReader(*conn), bufio.NewWriter(*conn))
	if tcpConnect == nil {
		logger.Info("找不到连接", clientid,this.Gt)
		return errors.New(fmt.Sprintf("找不到连接 client:%s 服务器信息:%v", clientid,this.Gt))
	}

	len, e := tcpConnect.Write(buf.Bytes())

	if e != nil {
		reason := fmt.Sprintf("connection:%s  ，error:%v %s %v", clientid, e, e.Error(),this.Gt)
		this.CM.DisConnection(this.Gt.Endpoint, reason)
	}
	if len == 0 {
		logger.Info(fmt.Sprintf("player:%s ，error:%v 发送数据长度0 ", clientid, e))
	}

	if err := tcpConnect.Flush(); err != nil {
		reason := fmt.Sprintf("connection:%s %v，error:%v %s", clientid, this.Gt, e, e.Error())
		this.CM.DisConnection(this.Gt.Endpoint, reason)
	}
	return nil
}
